package SocketServer.Driver;

import SocketServer.common.ReqEntity;
import SocketServer.handler.DictHandler;
import SocketServer.utils.DesKeyUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.net.ServerSocketFactory;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.InvalidKeyException;
import java.security.Key;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * socket server 驱动类
 */
public class ServerDriver {

    // Declare the port number
    private static int port = 3000;

    // Identifies the user number connected
    private static int counter = 0;

    //线程池
    private static ExecutorService handlerPool = null;

    //默认线程池容量为 10
    private static final Integer DEFAULT_POOL_SIZE = 10;

    //通信密钥
    Key key=null;

    public static void main(String[] args) {
        ServerDriver serverDriver = new ServerDriver();
        serverDriver.initServerDriver();
    }

    /**
     *  初始化驱动类
     */
    public void initServerDriver(){
        //创建一个有限的线程池
        handlerPool  = Executors.newFixedThreadPool(DEFAULT_POOL_SIZE);

        //server工厂方式创建
        ServerSocketFactory factory = ServerSocketFactory.getDefault();
        try(ServerSocket server = factory.createServerSocket(port)){
            System.out.println("Waiting for client connection..");
            // Wait for connections.
            while(true){
                Socket client = server.accept();
                counter++;
                System.out.println("Client "+counter+": Applying for connection!");
                // Start a new thread for a connection
//                Thread thread = new Thread(() -> serveClient(client));
                ServeClientThread thread = new ServeClientThread(client);
                handlerPool.execute(thread);//将线程放入线程池，无需再start
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //最后释放线程池资源
            handlerPool.shutdown();
        }
    }

    /**
     * 一个client一个thread
     */
    private class ServeClientThread implements Runnable{

        private Socket clientSocket = null;

        public  ServeClientThread(Socket clientSocket) {
            this.clientSocket = clientSocket;
        }

        @Override
        public void run() {
            try {
                // Input stream and Output Stream
                DataInputStream input = new DataInputStream(clientSocket.getInputStream());
                DataOutputStream output = new DataOutputStream(clientSocket.getOutputStream());
//                System.out.println("CLIENT: "+input.readUTF());
//                output.writeUTF("Server: Hi Client "+counter+" !!!");
                //先获取密钥部分
                DesKeyUtils des=new DesKeyUtils();
                //接收到base64编码后的密钥字符串
                String request=input.readUTF();
                //base64解密为普通二进制数组
                byte decodeMsg[]=des.decoder.decode(request);
                //根据二进制数组转换成key对象
                key=des.strToKey(decodeMsg);

                // Receive more data..
                while(true){
                    if(input.available() > 0){
                        // Attempt to convert read data to JSON
                        String command = input.readUTF();
                        command=des.decodeKey(command.getBytes(),key);
                        System.out.println("COMMAND RECEIVED: "+command);
                        ReqEntity reqEntity = JSON.parseObject(command, ReqEntity.class);
                        String result = handlerRouter(reqEntity);
                        JSONObject results = new JSONObject();
                        results.put("result", result);
                        output.writeUTF(results.toJSONString());
                    }
                }
            }catch (IOException |InvalidKeyException |IllegalBlockSizeException |BadPaddingException e) {
                e.printStackTrace();
            }finally {
                //释放资源

            }
        }
    }

    /**
     * 接口路由器，调用接口服务处理器DictHandler
     * @param reqEntity
     * @return
     */
    private static String  handlerRouter(ReqEntity reqEntity) {

        //获取DictHandler单例对象
        DictHandler dictHandler  = DictHandler.getInstance();
        //获取接口名称及参数
        String api = reqEntity.getSocketServerApi();
//        String jsonData = reqEntity.getJsonData();
        String result = "";
        switch(api){
            case "queryAllDict" :
                result = dictHandler.queryAllDict( reqEntity );
                break;
            case "findDict" :
                result = dictHandler.findDict( reqEntity );
                break;
            case "insertDict" :
                result = dictHandler.insertDict( reqEntity );
                break;
            case "deleteDict" :
                result = dictHandler.deleteDict( reqEntity );
                break;
            case "updateDict" :
                result = dictHandler.updateDict( reqEntity );
                break;
            case "findOptLogList" :
                result= dictHandler.findOptLogList( reqEntity );
                break;
            default :
                result = "查无该接口";
        }
        return result;
    }




}
